package interfaceusuario;

import entidadesparaguardardadosteste.CasoDeTeste;
import gui.FachadaManipulacaoClassesDeUmProjeto;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.LinkedList;

import javax.swing.DefaultListCellRenderer;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.ListSelectionModel;

public class TelaEscolhaClasseASerTestada implements MouseListener, ActionListener
{
	/**
	 * a TelaEscolhaClasseASerTestada eh a etapa 1 da criacao de um caso de testes. Por isso, ela
	 * contem um atributo casoDeTesteAssociado. Quando o usuario escolher a classe para testar, 
	 *  TelaEscolhaClasseASerTestada vai setar no caso de teste associado o nome da classe escolhida e encaminha 
	 *  os dados para a segunda etapa da criacao de um caso de testes: escolher um metodo para testar.
	 */
	private CasoDeTeste casoDeTesteAssociado;
	private LinkedList<String> nomesPacotesDeUmProjeto;
	private JList<String> listaDeItensApresentadaNaTela;
	private JFrame janelaEscolhaClasseASerTestada;
	private JButton botaoVoltarAListarPacotes;//botao vai voltar a listar os pacotes do projeto na tela
	private LinkedList<CasoDeTeste> casosDeTesteSendoCriados;
	private String pacoteEscolhido;
	
	private boolean projetoTemPacotes; //diz se o projeto a ser testado tem pacotes ou somente aquele "default package"
	
	
	public TelaEscolhaClasseASerTestada(String diretorioDoProjeto, LinkedList<CasoDeTeste> casosDeTesteSendoCriados)
	{
		this.casoDeTesteAssociado = casosDeTesteSendoCriados.getLast();//por enquanto, soh ha um caso de teste sendo criado. na outra tela eh que esse numero pode aumentar
		this.casosDeTesteSendoCriados = casosDeTesteSendoCriados;
		FachadaManipulacaoClassesDeUmProjeto fachadaManipulaClasses = FachadaManipulacaoClassesDeUmProjeto.getInstance();
		nomesPacotesDeUmProjeto = fachadaManipulaClasses.pegarTodosOsPacotesDoProjeto(diretorioDoProjeto);
		
		this.projetoTemPacotes = true; //vamos mudar esse booleano mais tarde se necessario
		
		
		
	}
	
	public void desenharTelaEscolhaClasseASerTestada()
	{
		this.janelaEscolhaClasseASerTestada = new JFrame("testboot- escolha classe para testar");
		this.janelaEscolhaClasseASerTestada.setVisible(false);
		this.janelaEscolhaClasseASerTestada.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
		this.janelaEscolhaClasseASerTestada.setSize(d);
		
		JPanel painelExplicacaoEscolhaClasse = this.criarPainelExplicacaoInformeClasseParaTestar();
		JPanel painelListaDePacotesDoProjeto = this.criarPainelListarPacotesDeUmProjeto();
		
		//agora, vamos criar o botao que volta a listar os pacotes de um projeto(inicialmente, ele fica oculto)
		this.botaoVoltarAListarPacotes = new JButton("Voltar");
		this.botaoVoltarAListarPacotes.addActionListener(this);
		this.botaoVoltarAListarPacotes.setVisible(false);
		
		JPanel painelEscolhaClassePraTestar = new JPanelComImagemDeFundo("imagens/backgroundTestboot.jpg");
		GridBagLayout layoutPainelescolhaClasseParaTestar = new GridBagLayout();
		painelEscolhaClassePraTestar.setLayout(layoutPainelescolhaClasseParaTestar);
		GridBagConstraints g = new GridBagConstraints();
		g.gridx = 0;
		g.gridy = 0;
		g.gridheight = 3;
		painelEscolhaClassePraTestar.add(painelExplicacaoEscolhaClasse, g);
		
		g.gridy = 3;
		g.gridheight = 5;
		painelEscolhaClassePraTestar.add(painelListaDePacotesDoProjeto, g);
		
		g.gridy = 8;
		g.gridheight = 1;
		g.insets = new Insets(20, 0, 0, 0);
		painelEscolhaClassePraTestar.add(botaoVoltarAListarPacotes, g);
		
		janelaEscolhaClasseASerTestada.add(painelEscolhaClassePraTestar);
		
		System.out.println("primeiro pacote do projeto:" + this.nomesPacotesDeUmProjeto.get(0));
		if(this.nomesPacotesDeUmProjeto.get(0).compareTo("") == 0)
		{
			//se o nome do primeiro pacote do projeto eh "", significa que o projeto nao tem pacotes
			//vamos mostrar logo as classes carregadas, nunca os pacotes
			this.projetoTemPacotes = false;
			this.apresentarClassesDoPacoteSelecionado("");
		}
		
		janelaEscolhaClasseASerTestada.setVisible(true);
	}
	
	
	
	private JPanel criarPainelExplicacaoInformeClasseParaTestar()
	{
		String descricaoTestboot = "Por favor, escolha um pacote do projeto e a classe que deseja testar:";
		JLabel labelDescricao = CriadorTextLabel.criarTextLabel(descricaoTestboot);
		JPanel painelExplicacao = new JPanel();
		painelExplicacao.setBackground(new Color(230,175,172));
		painelExplicacao.add(labelDescricao);
		return painelExplicacao;
	}
	
	private JPanel criarPainelListarPacotesDeUmProjeto()
	{
		listaDeItensApresentadaNaTela = new JList<String>();
		listaDeItensApresentadaNaTela.setBackground(new Color(230,175,172));
		listaDeItensApresentadaNaTela.setForeground(new Color(111, 77, 138));
		listaDeItensApresentadaNaTela.setFont(new Font("Berlin Sans FB Demi", 1, 18));
		listaDeItensApresentadaNaTela.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);  
        //precisamos centralizar os itens da lista...
		DefaultListCellRenderer renderer =  
                                    (DefaultListCellRenderer)listaDeItensApresentadaNaTela.getCellRenderer();  
        renderer.setHorizontalAlignment(JLabel.CENTER); 
		
		//temos de mudar nossa JList para apresentar os pacotes do projeto.
		this.mudarListaDeItensApresentadaNaTela(this.nomesPacotesDeUmProjeto);
		listaDeItensApresentadaNaTela.addMouseListener(this);
		JPanel painelListaDePacotes = new JPanel();
		//vamos soh botar a lista em um scrollpane antes de adicionar ao painel definitivamente...
		JScrollPane painelRolagemParaListaDePacotes = new JScrollPane(listaDeItensApresentadaNaTela);
		painelRolagemParaListaDePacotes.setPreferredSize(new Dimension(700, 400));
		painelListaDePacotes.add(painelRolagemParaListaDePacotes);
		return painelListaDePacotes;
		
	}
	
	public void mudarListaDeItensApresentadaNaTela(LinkedList<String> novaListagemDeItens)
	{
		//temos de converter nossa LinkedList em um arranjo
		String [] arranjoNovaListagemDeItens = new String[novaListagemDeItens.size()];
		for(int i = 0; i < novaListagemDeItens.size(); i++)
		{
			String itemDaLista = novaListagemDeItens.get(i);
			arranjoNovaListagemDeItens[i] = itemDaLista;
		}
		listaDeItensApresentadaNaTela.setListData(arranjoNovaListagemDeItens);
	}

	@Override
	public void mouseClicked(MouseEvent arg0) 
	{
		Object fonteDoClique = arg0.getSource();
		if(fonteDoClique == this.listaDeItensApresentadaNaTela && arg0.getClickCount() == 2 & this.projetoTemPacotes == true)
		{
			String diretorioSelecionado = this.listaDeItensApresentadaNaTela.getSelectedValue();
			if(nomesPacotesDeUmProjeto.contains(diretorioSelecionado) != true)
			{
				//o usuario acaba de selecionar uma classe
				this.casoDeTesteAssociado.setNomeClasseAssociadaAoCasoDeTeste(this.pacoteEscolhido + "." + diretorioSelecionado);
				//o usuario agora vai passar para a etapa 2: escolher o metodo da classe que deseja testar no caso de teste.
				TelaEscolhaMetodoASerTestado telaEscolhaMetodoParaTestar = new TelaEscolhaMetodoASerTestado(this.casosDeTesteSendoCriados); 
				janelaEscolhaClasseASerTestada.dispose();
			}
			else
			{
				//o usuario acaba de selecionar um pacote do projeto
				this.apresentarClassesDoPacoteSelecionado(diretorioSelecionado);
				//tem de ter uma opcao para  usuario voltar a ver os pacotes do projeto caso queira
				this.botaoVoltarAListarPacotes.setVisible(true);
			}
		}
		else if(fonteDoClique == this.listaDeItensApresentadaNaTela && arg0.getClickCount() == 2 & this.projetoTemPacotes == false)
		{
			String classeSelecionada = this.listaDeItensApresentadaNaTela.getSelectedValue();
			//o usuario acaba de selecionar uma classe, ja que o projeto nao tem pacotes
			this.casoDeTesteAssociado.setNomeClasseAssociadaAoCasoDeTeste(classeSelecionada);
			//o usuario agora vai passar para a etapa 2: escolher o metodo da classe que deseja testar no caso de teste.
			TelaEscolhaMetodoASerTestado telaEscolhaMetodoParaTestar = new TelaEscolhaMetodoASerTestado(this.casosDeTesteSendoCriados); 
			janelaEscolhaClasseASerTestada.dispose();
		}
		
	}
	
	public void apresentarClassesDoPacoteSelecionado(String pacoteSelecionado)
	{
		this.pacoteEscolhido = pacoteSelecionado;
		FachadaManipulacaoClassesDeUmProjeto fachadaManipulaClasses = FachadaManipulacaoClassesDeUmProjeto.getInstance();
		LinkedList<String> nomesClassesDoPacoteSelecionado = fachadaManipulaClasses.pegarNomesDasClassesDentroDeUmPacote(pacoteSelecionado);
		//temos de mudar nossa JList para mostrar as classes contidas no acote selecionado.
		this.mudarListaDeItensApresentadaNaTela(nomesClassesDoPacoteSelecionado);
	}

	@Override
	public void mouseEntered(MouseEvent arg0) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void mouseExited(MouseEvent arg0) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void mousePressed(MouseEvent arg0) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void mouseReleased(MouseEvent arg0) {
		// TODO Auto-generated method stub
		
	}
	
	

	@Override
	public void actionPerformed(ActionEvent arg0) 
	{
		Object objetoDaAcao = arg0.getSource();
		if(objetoDaAcao == this.botaoVoltarAListarPacotes)
		{
			this.mudarListaDeItensApresentadaNaTela(nomesPacotesDeUmProjeto);
			this.botaoVoltarAListarPacotes.setVisible(false);
		}
		
	}
	
	

}
